堆溢出(三)快表DWORD SHOOT
 
本系列文章讲述了windows 2000 下 堆溢出的方法
0x000 环境
- 虚拟机 VirtualBox 5.0.20
- 系统 windows 2000 Kali linux
- 工具 VC++6.0 OllyDbg 1.10 汉化版 AsmToE v5.20
0x001堆溢出之快表
- 代码
|
|
- 快表溢出原理及现象分析
a) 由第一篇中的知识,可知道快表中单链表,它和空表不同,下面就讲一下我是如何利用的。
b) 首先编译上面的代码,运行,OD附加等等,这里不在多说了,单步执行或者加断点,跳过前面堆块分配的过程,分配后的堆情况如下图。选中部分即新分配的三个堆块。
c) 下面将第二块释放掉,可以转到快表头去看,可以看到第二块数据的地址被写到其中了,具体如下图。这里讲一下单链表的操作,这里是一个单链表的一个插入,下次分配数据会从Look[2]的数据项寻找对应的堆块,如果存在,会将链表中下一个节点中存储下下个节点的地址写入到头中,以便下次从快表中分配。
d) 结合源代码可以看出下一步发生了溢出,复制的数据将第一个链表的数据域填充满了以后,又将下一块也就是第二块的头覆盖掉了,再加上四个字节的大小(结合上面的两个图,可以算出来,这里正是Look[2]中存储的地址,如果这里被修改,下次分配内存的地址将会改变),在这些过程执行之后,堆中变化如下图,这里我将下次分配的地址(重定向到)堆上的另一地址0x00362380,现在还没有写入到Look[2]。
e) 下面,程序再次申请了一块同样大小的内存,由第一篇文章可以知道,这里会从快表分配,如果没有发生溢出程序运行之后,会将0x00361ea0的数据(0x00000000)写Look[2]中,Look[2]就为空了,但是溢出之后,程序就是将现在的数据写入了Look[2]中,Look[2]不为空了,下次分配会从这个写入的地址开始分配,执行后的快表数组如下,可以看到值果然变成了0x00362380。
f) 程序再次分配内存,会在上面的那个地址分配,我们来验证一下,我们可以看一下函数执行的返回值,正是我们重定向后的地址,堆块分配成功了。
g) 我们转到上面的地址,继续运行程序,这里向新分配的内存中写入了“XXXX”这个字符串,这里一个更明显的看到上面这个结果,具体如下图 - 总结
通过上面的小程序,我们很清楚的明白了快表的堆溢出,可以向劫持的地址写入任意数据,我们也知道了怎么利用快表的,快表的工作原理,攻击方法等等,下面我们将植入shellcode完全利用这个程序。
0x002 DWROD SHOOT代码植入 - 修改代码
|
|
- 植入shell code
a) 确定劫持地址
这次的利用和上一篇的空表利用几乎是一样的,相同的地方我不在多赘述,这里利用的地址也是RtlEnterCriticalSection,它的地址为0x7ffdf020,寻找方法上一篇也提到了,不会的可以去寻找查看一下。
b) 确定shellcode地址
这里比上一面程序多申请了一块内存存放shellcode,通过调试我确定再我机子上是0x00361ec0
c) Shellcode
Shellcode和之前使用kali生成的shellcode一样
d) 植入
通过上面的小程序,我们可以将RtlEnterCriticalSection的地址设置为劫持地址,再将我们的shellcode地址写入就可以了,
可以结合源代码的40和62行来看是怎么做的。
e) 运行结果
f) 与空表的区别
要注意上面的shellcode,对系统的修复工作要增加,如果只是按照空表来修复的话,shellcode不会正确被执行,这里我也是调试好久才发现,在将堆块劫持到新的位置的时候,堆块的头会破坏上面的数据,引发异常,如下图中,第一个红框的位置,就是对RtlEnterCriticalSection减4的地址的数据进行修复,同样使用上面的AsmToE工具将汇编转换成机器码,在代码的的旁边我也注释汇编代码,第二个红框和空表的修复是一样的。0x003 总结
堆溢出这一系列的文章目前写完,这对我调试能力和分析设计能力都有很大的提高,对堆的理解也更加深入了。0x004 参考书籍
[1]《0day安全 软件漏洞分析技术 (第二版)》王清
[2]《软件调试》张银奎